<h2>Why is this an issue?</h2>
<p>In C#, the <a href="https://learn.microsoft.com/en-us/dotnet/api/system.object.referenceequals"><code>Object.ReferenceEquals</code></a> method is
used to compare two <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types">reference type</a>
variables. If you use this method to compare two <a
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types">value types</a>, such as <code>int</code>,
<code>float</code>, or <code>bool</code> you will not get the expected results because value type variables contain an instance of the type and not a
reference to it.</p>
<p>Due to value type variables containing directly an instance of the type, they can’t have the same reference, and using
<code>Object.ReferenceEquals</code> to compare them will always return <code>false</code> even if the compared variables have the same value.</p>
<h2>How to fix it</h2>
<p>When comparing value types, prefer using the <a
href="https://learn.microsoft.com/en-us/dotnet/api/system.object.equals"><code>Object.Equals</code></a>.</p>
<p>Note that in the case of <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct">structure types</a>, it
is recommended to <a
href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type#struct-example">implement
value equality</a>. If not, {rule:csharpsquid:S3898} might raise.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
using System;

struct MyStruct
{
    int valueA;
    int valueB;
}

static class MyClass
{
    public static void Method(MyStruct struct1, MyStruct struct2)
    {
        if (Object.ReferenceEquals(struct1, struct2)) // Noncompliant: this will be always false
        {
            // ...
        }
    }
}
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
using System;

struct MyStruct : IEquatable&lt;MyStruct&gt;
{
    int valueA;
    int valueB;

    public bool Equals(MyStruct other) =&gt; valueA == other.valueA &amp;&amp; valueB == other.valueB;

    public override bool Equals(object obj) =&gt; obj is MyStruct other &amp;&amp; Equals(other);

    public override int GetHashCode() =&gt; HashCode.Combine(valueA, valueB);

    public static bool operator ==(MyStruct lhs, MyStruct rhs) =&gt; lhs.Equals(rhs);

    public static bool operator !=(MyStruct lhs, MyStruct rhs) =&gt; !(lhs == rhs);
}

static class MyClass
{
    public static void Method(MyStruct struct1, MyStruct struct2)
    {
        if (struct1.Equals(struct2)) // Compliant: value are compared
        {
            // ...
        }
    }
}
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/system.object.referenceequals"><code>Object.ReferenceEquals(Object,
  Object)</code> Method</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/system.object.equals"><code>Object.Equals</code> Method</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types">Value types (C#
  reference)</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types">Reference types (C#
  reference)</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-operators">Equality operators
  - test if two objects are equal or not</a> </li>
  <li> Microsoft Learn - <a
  href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type#struct-example">How to define value equality for a class or struct (C# Programming Guide)</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct">Structure types (C#
  reference)</a> </li>
  <li> {rule:csharpsquid:S3898} - Value types should implement "IEquatable&lt;T&gt;" </li>
</ul>

